package com.ala4.oxcafe.common.utils.date;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;

/**
 * 时间工具类
 *
 * @author PING
 * @version 1.0.0
 * @date 2025/7/31 16:48
 */
public class DateUtil {

    private DateUtil() {
    }

    /**
     * 当前时间的时间戳（秒）
     *
     * @return 当前时间秒数
     */
    public static long currentSeconds() {
        return System.currentTimeMillis() / 1000;
    }

    // 常用日期时间格式
    public static final String DATE_FORMAT = "yyyy-MM-dd";
    public static final String TIME_FORMAT = "HH:mm:ss";
    public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String TIMESTAMP_FORMAT = "yyyyMMddHHmmssSSS";

    // ================== 基础方法 ==================

    /**
     * 获取当前日期 (LocalDate)
     */
    public static LocalDate nowDate() {
        return LocalDate.now();
    }

    /**
     * 获取当前时间 (LocalTime)
     */
    public static LocalTime nowTime() {
        return LocalTime.now();
    }

    /**
     * 获取当前日期时间 (LocalDateTime)
     */
    public static LocalDateTime nowDateTime() {
        return LocalDateTime.now();
    }

    /**
     * 获取当前时间戳 (毫秒)
     */
    public static long currentTimestamp() {
        return System.currentTimeMillis();
    }

    // ================== 格式转换 ==================

    /**
     * 日期转字符串 (默认格式 yyyy-MM-dd)
     */
    public static String dateToString(LocalDate date) {
        return dateToString(date, DATE_FORMAT);
    }

    /**
     * 日期时间转字符串 (默认格式 yyyy-MM-dd HH:mm:ss)
     */
    public static String dateTimeToString(LocalDateTime dateTime) {
        return dateTimeToString(dateTime, DATETIME_FORMAT);
    }

    /**
     * 日期转字符串 (自定义格式)
     */
    public static String dateToString(LocalDate date, String pattern) {
        return date.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 日期时间转字符串 (自定义格式)
     */
    public static String dateTimeToString(LocalDateTime dateTime, String pattern) {
        return dateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 字符串转日期 (默认格式 yyyy-MM-dd)
     */
    public static LocalDate stringToDate(String dateStr) {
        return stringToDate(dateStr, DATE_FORMAT);
    }

    /**
     * 字符串转日期时间 (默认格式 yyyy-MM-dd HH:mm:ss)
     */
    public static LocalDateTime stringToDateTime(String dateTimeStr) {
        return stringToDateTime(dateTimeStr, DATETIME_FORMAT);
    }

    /**
     * 字符串转日期 (自定义格式)
     */
    public static LocalDate stringToDate(String dateStr, String pattern) {
        return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * 字符串转日期时间 (自定义格式)
     */
    public static LocalDateTime stringToDateTime(String dateTimeStr, String pattern) {
        return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
    }

    /**
     * Date 转 LocalDateTime
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * LocalDateTime 转 Date
     */
    public static Date localDateTimeToDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    // ================== 日期计算 ==================

    /**
     * 日期加减天数
     */
    public static LocalDate plusDays(LocalDate date, int days) {
        return date.plusDays(days);
    }

    /**
     * 日期加减月份
     */
    public static LocalDate plusMonths(LocalDate date, int months) {
        return date.plusMonths(months);
    }

    /**
     * 日期加减年份
     */
    public static LocalDate plusYears(LocalDate date, int years) {
        return date.plusYears(years);
    }

    /**
     * 日期时间加减分钟
     */
    public static LocalDateTime plusMinutes(LocalDateTime dateTime, int minutes) {
        return dateTime.plusMinutes(minutes);
    }

    /**
     * 日期时间加减小时
     */
    public static LocalDateTime plusHours(LocalDateTime dateTime, int hours) {
        return dateTime.plusHours(hours);
    }

    // ================== 日期比较 ==================

    /**
     * 比较两个日期先后 (date1在date2之后返回true)
     */
    public static boolean isAfter(LocalDate date1, LocalDate date2) {
        return date1.isAfter(date2);
    }

    /**
     * 比较两个日期时间先后
     */
    public static boolean isAfter(LocalDateTime time1, LocalDateTime time2) {
        return time1.isAfter(time2);
    }

    /**
     * 计算两个日期相差天数
     */
    public static long daysBetween(LocalDate start, LocalDate end) {
        return ChronoUnit.DAYS.between(start, end);
    }

    /**
     * 计算两个日期时间相差分钟数
     */
    public static long minutesBetween(LocalDateTime start, LocalDateTime end) {
        return ChronoUnit.MINUTES.between(start, end);
    }

    // ================== 特殊日期获取 ==================

    /**
     * 获取当月第一天
     */
    public static LocalDate firstDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 获取当月最后一天
     */
    public static LocalDate lastDayOfMonth(LocalDate date) {
        return date.with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 获取本周周一
     */
    public static LocalDate firstDayOfWeek(LocalDate date) {
        return date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
    }

    /**
     * 获取本周周日
     */
    public static LocalDate lastDayOfWeek(LocalDate date) {
        return date.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
    }

    // ================== 日期判断 ==================

    /**
     * 判断是否周末
     */
    public static boolean isWeekend(LocalDate date) {
        DayOfWeek day = date.getDayOfWeek();
        return day == DayOfWeek.SATURDAY || day == DayOfWeek.SUNDAY;
    }

    /**
     * 判断是否闰年
     */
    public static boolean isLeapYear(LocalDate date) {
        return date.isLeapYear();
    }

    /**
     * 判断两个日期是否同一天
     */
    public static boolean isSameDay(LocalDate date1, LocalDate date2) {
        return date1.isEqual(date2);
    }

    /**
     * 判断日期是否在范围内 (包含边界)
     */
    public static boolean isBetween(LocalDate date, LocalDate start, LocalDate end) {
        return !date.isBefore(start) && !date.isAfter(end);
    }

    // ================== 时间操作 ==================

    /**
     * 获取时间戳字符串 (yyyyMMddHHmmssSSS)
     */
    public static String nowDateString() {
        return nowDateTime().format(DateTimeFormatter.ofPattern(TIMESTAMP_FORMAT));
    }

    public static String nowDateString(String format) {
        return nowDateTime().format(DateTimeFormatter.ofPattern(format));
    }

    /**
     * 获取当天开始时间 (00:00:00)
     */
    public static LocalDateTime startOfDay(LocalDate date) {
        return date.atStartOfDay();
    }

    /**
     * 获取当天结束时间 (23:59:59.999)
     */
    public static LocalDateTime endOfDay(LocalDate date) {
        return date.atTime(LocalTime.MAX);
    }

    // ================== 时区转换 ==================

    /**
     * 转换时区 (默认系统时区 → 目标时区)
     */
    public static ZonedDateTime convertZone(LocalDateTime localDateTime, String targetZoneId) {
        return localDateTime.atZone(ZoneId.systemDefault())
                .withZoneSameInstant(ZoneId.of(targetZoneId));
    }

    /**
     * 获取不同时区的当前时间
     */
    public static LocalDateTime nowInZone(String zoneId) {
        return LocalDateTime.now(ZoneId.of(zoneId));
    }

}
